module Main (main) where

import Types
import ParseWSDL
import ProxyWSDL
import System.Directory
import Control.Monad
import qualified Data.Map as Map
import System.FilePath.Posix
import System.Environment (getArgs)
import Data.Maybe
import Text.Printf
import System.IO.UTF8 (writeFile)
import Prelude hiding (readFile, writeFile)

main :: IO ()
main = getArgs >>= run

pgArgs :: [(String, [String] -> IO ())]
pgArgs = [ ("--h", (\_ -> putStr . unlines $ ["Available params are:", "\t--h : See this help", "\t--g <wsdl-root> <gen-path> [<gen-package>]"])),
            ("--g", generate) ]

run :: [String] -> IO ()
run [] = run ["--h"]
run args = fromMaybe (error . printf ("The argument %s is unknown. " ++ seeHelp) . head) (lookup (head args) pgArgs) args
    
seeHelp :: String
seeHelp = "To see help use --h option."    

generate :: [String] -> IO ()
generate args
    | length args < 3 = error $ "Not ehough parameters. " ++ seeHelp
    | otherwise = do
        p <- getCurrentDirectory
        setCurrentDirectory (args!!1)
        s <- liftM (map ((args!!1) ++) . filter (`notElem` [".", "..", ".svn"])) 
                (getDirectoryContents "." >>= filterM doesDirectoryExist) 
        setCurrentDirectory p >> createDirectoryIfMissing True (args!!2) >> setCurrentDirectory (args!!2)

        foldM_ (\m x -> do
            (m', y) <- print x >> parseWSDL m x 
            zipWithM_ create_and_write (genProxy y (if length args < 4 then "" else args!!3))
                    $ map ((++".hs") . ('.':) . (pathSeparator:) . map (\ch -> if ch `elem` "./" then pathSeparator else ch) . 
                        upperAfterDot . snd . getPrefName . snd . head . wssNamespaces) $ wsdSchemas y 
            return m'
            ) (Map.empty::(Map.Map String [WsType])) s
        setCurrentDirectory p            
    where
        create_and_write content file_path = 
            do
                createDirectoryIfMissing True $ dropFileName file_path
                writeFile file_path content
